package net.eicp.jxcontent.core.snippet

import scala.xml._
import net.eicp.jxcontent.core.snippet._
import scala.beans.BeanProperty
import net.liftweb.common._
import scala.collection.GenTraversable
import scala.collection.mutable.Map

trait JXDispatchSnippet {
  
  import scala.language.implicitConversions
  implicit def int2JXProcessLevel(level: Int) = JXProcessLevel(level)
  
  type dispatchIt = PartialFunction[String, JXSnippetScope => JXProcessChannel]
  def dispatch: dispatchIt
  
  //def copyObject: this.type = throw new Exception("JXDispatchSnippet中copyObject方法还没有子类的实现，请在appendSnippetDispatch的时候用  JXCopy[类名]  代替")
  
}

case class JXProcessChannel(processElem: List[JXProcessElem]) {
  def &(other: JXProcessChannel) = JXProcessChannel(processElem ::: other.processElem)
}

abstract class JXProcessElem
case class JXProcessElemAny(level: JXProcessLevel, process: () => Any) extends JXProcessElem
case class JXProcessElemXhtml(level: JXProcessLevel, process: NodeSeq => NodeSeq) extends JXProcessElem

case class JXProcessLevel(level: Int) {
  def =>>(process: () => Any) = JXProcessChannel(List(JXProcessElemAny(this, process)))
  def ===(process: NodeSeq => NodeSeq) = JXProcessChannel(List(JXProcessElemXhtml(this, process)))
}

class JXSnippetScope {
  
  var snippetVarList = List.empty[Any]
  
  import scala.language.implicitConversions
  implicit def int2JXProcessLevel(level: Int) = JXProcessLevel(level)
  
  def save[T](input: T): T = {
    snippetVarList = input :: snippetVarList
    input
  }
  
  def update[T](filter: PartialFunction[Any, T]): Box[T] = {
    getVal(filter) match {
      case result@Full(s) => { snippetVarList = s :: snippetVarList; result }
      case _ => Empty
    }
  }
  
  def saveOrUpdate[T](filter: PartialFunction[Any, T])(default: T) = {
    update(filter) openOr save(default)
  }
  
  def getVal[T](filter: PartialFunction[Any, T]): Box[T] = {
    val element: Box[Any] = snippetVarList.find(s => filter.isDefinedAt(s))
    element match {
      case Full(s) => Full(filter(s))
      case _ => Empty
    }
  }
  
}